package com.wmlt.danmaku.app.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wmlt.danmaku.app.bean.Danmaku;
import org.springframework.stereotype.Component;


import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Comparator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListSet;

@ServerEndpoint(value = "/api/websocket/message/{roomId}")
@Component
public class WebSocketService {


    private static final ConcurrentMap<String, ConcurrentSkipListSet<Session>> clients = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("roomId") String roomId) throws IOException {
        String uri = session.getRequestURI().getPath()+roomId;
        if(!clients.containsKey(uri)) {
            clients.putIfAbsent(uri, new ConcurrentSkipListSet<>(Comparator.comparing(Session::getId)));
        }
        ConcurrentSkipListSet<Session> set = clients.get(uri);
        set.add(session);
    }



    @OnMessage
    public void onMessage(Session session, String text, @PathParam("roomId") String roomId) {
        if(text == null) {
            return;
        }
        Danmaku danmaku = Danmaku.fromJSON(JSONObject.parseObject(text));
        String value = JSON.toJSONString(danmaku);
        String uri = session.getRequestURI().getPath()+ roomId;
        ConcurrentSkipListSet<Session> set = clients.get(uri);
        set.forEach(v -> {
            if(v == session) {
                return;
            } else if(!v.isOpen()) {
                set.remove(v);
            } else {
                v.getAsyncRemote().sendText(value);
            }
        });
        System.out.println("监听消息"+value);
    }

    @OnError
    public void onError(Session session, Throwable throwable, @PathParam("roomId") String roomId) throws IOException {
        session.close();
        onClose(session,roomId);
    }

    @OnClose
    public void onClose(Session session, @PathParam("roomId") String roomId) {
        session.getRequestURI();
        ConcurrentSkipListSet<Session> roomSet = clients.get(session.getRequestURI().getPath()+roomId);
        if(roomSet != null) {
            roomSet.remove(session);
        }
    }

}
